<template>
    <component :is="FormItem" :label="Item.Label" :unit="Item.Unit" v-model="Value" :distName="Item.Dist" />
</template>
<script setup>
import { shallowRef, ref, onMounted, watch } from 'vue'
import InputVue from './Input.vue';
import InputNumberVue from './InputNumber.vue';
import SelectVue from './Select.vue';

const FormItemMapping = {
    Input: InputVue,
    InputNumber: InputNumberVue,
    Select: SelectVue,
}

const FormItem = shallowRef();
// 为每个表单元素单独创建一个变量的缓存空间
const Value = ref();

const props = defineProps({
    Item: Object,
    Value: [Object, Array],
});

const emit = defineEmits(['ChangeValue'])

onMounted(() => {
    // 利用 Mapping 来更新表单元素的动态类型绑定
    FormItem.value = FormItemMapping[props.Item.FormItemType];
});

// 外部数据变化时，则更新内部值变化，
// 利用深度监听与初次执行来解决值加载与赋值问题
watch(() => props.Value, (val) => {
    var FunString = new Function("val", "return val." + props.Item.Key);
    Value.value = FunString(val);
}, { immediate: true, deep: true });

// 内部数据变化时，则更新外部数据，
// 因为传值并不是双向绑定的，并且也不想破坏双向绑定的对象关系
// 所以利用这种方式对改变值得方法进行操作
watch(Value, (val) => {
    emit('ChangeValue', val, props.Item)
})



</script>
<style lang="less" scoped>

</style>